#include "Semaforo.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include "GenericException.h"

Semaforo::Semaforo(int valorInicial)throw (GenericException){
	semid = semget(IPC_PRIVATE, 1, 0666);
	if(semid == -1)
		throw GenericException("No se pudo crear el semaforo.");
	setValue(valorInicial);
}

bool Semaforo::setValue(int valor){
	union semun {
		int              val;    /* Value for SETVAL */
		struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
		unsigned short  *array;  /* Array for GETALL, SETALL */
		struct seminfo  *__buf;  /* Buffer for IPC_INFO
					    (Linux-specific) */
	}init;

	init.val = valor;

	if(semctl(semid, 0, SETVAL, init)==-1)
		throw GenericException("Error al asignar valor al semáforo.");

	return true;
}

void Semaforo::wait(){
	struct sembuf op;
	op.sem_op = -1;
	op.sem_flg = 0;
	op.sem_num = 0;
	if(semop(semid, &op, 1)==-1)
		throw GenericException("Error al esperar al semaforo.");
}

void Semaforo::signal(){
	struct sembuf op;
	op.sem_op = 1;
	op.sem_flg = 0;
	op.sem_num = 0;
	if(semop(semid, &op, 1)==-1)
		throw GenericException("Error al utilizar el semaforo.");
}

Semaforo::~Semaforo(){
	semctl(semid, 0, IPC_RMID);
}
